package com.adams.custom.page.core.dao.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;

import com.adams.access.db.bean.DicColumn;
import com.adams.access.db.bean.DicColumnPK;
import com.adams.access.db.dao.hibernate.HibernateGenericDao;
import com.adams.core.exception.BusinessException;
import com.adams.custom.page.util.ViewCacheUtil;
import com.adams.custom.page.util.ViewUtil;

/**
 * 
 * File Name : DicColumnDaoImpl.java
 * 
 * @Description : 字段定义数据访问实现类
 */
public class DicColumnDaoImpl extends
		HibernateGenericDao<DicColumn, DicColumnPK>
{
	Logger logger = Logger.getLogger(DicColumnDaoImpl.class.getName());

	private static String cacheMapByPk_key = "DicColumn_cacheMapByPk";

	private static String cacheMapByTablecode_key = "DicColumn_cacheMapByTablecode";

	private static String cacheMapByTablecodeAndRddcolumn_key = "DicColumn_cacheMapByTablecodeAndRddcolumn";

	private static String cacheMapBySourcetable_key = "DicColumn_cacheMapBySourcetable";

	private static String cacheMapByRddsourcetable_key = "DicColumn_cacheMapByRddsourcetable";

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.adams.access.db.dao.hibernate.HibernateGenericDao#save(java
	 * .lang.Object)
	 */
	public void save(DicColumn model)
	{
		super.save(model);
		synchronizationCache();
	}

	/**
	 * Description : 根据表编码及字段编码获得字段定义
	 * 
	 * @param tablecode
	 * @param columncode
	 * @return
	 * @throws Exception
	 * 
	 */
	@SuppressWarnings("unchecked")
	public DicColumn get(String tablecode, String columncode)
			throws BusinessException
	{
		DicColumnPK pk = new DicColumnPK(tablecode, columncode);
		Map cacheMapByPk = ViewCacheUtil.getConfigDataCacheMap(cacheMapByPk_key);
		if (!cacheMapByPk.containsKey(pk))
		{
			synchronizationCache();
		}
		DicColumn result = (DicColumn) cacheMapByPk.get(pk);
		if (null == result)
		{
			logger.error(tablecode + "表" + columncode + "字段定义不存在！");
			throw new BusinessException("column.config.notexists.exception");
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.adams.access.db.dao.hibernate.HibernateGenericDao#delete(java
	 * .lang.Object)
	 */
	public void delete(DicColumn model)
	{
		super.delete(model);
		synchronizationCache();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.adams.access.db.dao.hibernate.HibernateGenericDao#update(java
	 * .lang.Object)
	 */
	public void update(DicColumn model)
	{
		super.saveOrUpdate(model);
		synchronizationCache();
	}

	/**
	 * Description : 根据表编码查询字段定义
	 * 
	 * @param tablecode
	 * @return
	 * 
	 */
	@SuppressWarnings("unchecked")
	public List<DicColumn> findByTablecode(String tablecode)
	{
		Map cacheMapByTablecode = ViewCacheUtil
				.getConfigDataCacheMap(cacheMapByTablecode_key);
		if (!cacheMapByTablecode.containsKey(tablecode))
		{
			synchronizationCache();
		}
		List<DicColumn> result = new ArrayList<DicColumn>();
		List<DicColumn> temp = (List<DicColumn>) cacheMapByTablecode
				.get(tablecode);
		if (null != temp)
		{
			result.addAll(temp);
			// sort(result);
		}
		return result;
	}

	/**
	 * Description : 根据表编码查询冗余字段定义
	 * 
	 * @param tablecode
	 * @return
	 * 
	 */
	@SuppressWarnings("unchecked")
	public List<DicColumn> findRddcolumnByTablecode(String tablecode)
	{
		Map cacheMapByTablecodeAndRddcolumn = ViewCacheUtil
				.getConfigDataCacheMap(cacheMapByTablecodeAndRddcolumn_key);
		if (!cacheMapByTablecodeAndRddcolumn.containsKey(tablecode))
		{
			synchronizationCache();
		}
		List<DicColumn> result = new ArrayList<DicColumn>();
		List<DicColumn> temp = (List<DicColumn>) cacheMapByTablecodeAndRddcolumn
				.get(tablecode);
		if (null != temp)
		{
			result.addAll(temp);
		}
		return result;
	}

	/**
	 * Description : 根据表编码查询字段定义
	 * 
	 * @param tablecode
	 * @return
	 * 
	 */
	@SuppressWarnings("unchecked")
	public List<DicColumn> findBySourcetablecode(String sourcetablecode)
	{
		Map cacheMapBySourcetable = ViewCacheUtil
				.getConfigDataCacheMap(cacheMapBySourcetable_key);
		if (!cacheMapBySourcetable.containsKey(sourcetablecode))
		{
			synchronizationCache();
		}
		List<DicColumn> result = new ArrayList<DicColumn>();
		List<DicColumn> temp = (List<DicColumn>) cacheMapBySourcetable
				.get(sourcetablecode);
		if (null != temp)
		{
			result.addAll(temp);
			// sort(result);
		}
		return result;
	}

	/**
	 * Description : 根据来源数据表编码查询冗余字段定义
	 * 
	 * @param tablecode
	 * @return
	 * 
	 */
	@SuppressWarnings("unchecked")
	public List<DicColumn> findByRddsourcetablecode(String rddsourcetable)
	{
		Map cacheMapByRddsourcetable = ViewCacheUtil
				.getConfigDataCacheMap(cacheMapByRddsourcetable_key);
		if (!cacheMapByRddsourcetable.containsKey(rddsourcetable))
		{
			synchronizationCache();
		}
		List<DicColumn> result = new ArrayList<DicColumn>();
		List<DicColumn> temp = (List<DicColumn>) cacheMapByRddsourcetable
				.get(rddsourcetable);
		if (null != temp)
		{
			result.addAll(temp);
			// sort(result);
		}
		return result;
	}

	private void sort(List<DicColumn> result)
	{
		if (null == result || result.size() == 0)
		{
			return;
		}
		Collections.sort(result, new Comparator<DicColumn>()
		{
			@Override
			public int compare(DicColumn o1, DicColumn o2)
			{
				// TODO Auto-generated method stub
				return o1.getDicColumnPK().getColumncode().compareTo(
						o2.getDicColumnPK().getColumncode());
			}

		});
	}

	private List<DicColumn> findAllFromDB()
	{
		List<DicColumn> result = query("from DicColumn");
		return result;
	}

	/**
	 * Description : 同步缓存
	 * 
	 * @return
	 * 
	 */
	@SuppressWarnings("unchecked")
	public synchronized List<DicColumn> synchronizationCache()
	{
		List<DicColumn> result = findAllFromDB();
		Map cacheMapByPk = ViewCacheUtil.getConfigDataCacheMap(cacheMapByPk_key);
		Map cacheMapByTablecode = ViewCacheUtil
				.getConfigDataCacheMap(cacheMapByTablecode_key);
		cacheMapByTablecode.clear();

		Map cacheMapByTablecodeAndRddcolumn = ViewCacheUtil
				.getConfigDataCacheMap(cacheMapByTablecodeAndRddcolumn_key);
		cacheMapByTablecodeAndRddcolumn.clear();

		Map cacheMapBySourcetable = ViewCacheUtil
				.getConfigDataCacheMap(cacheMapBySourcetable_key);
		cacheMapBySourcetable.clear();

		Map cacheMapByRddsourcetable = ViewCacheUtil
				.getConfigDataCacheMap(cacheMapByRddsourcetable_key);
		cacheMapByRddsourcetable.clear();

		for (DicColumn dicColumn : result)
		{
			cacheMapByPk.put(dicColumn.getDicColumnPK(), dicColumn);
			// 表字段缓存
			String tablecode = dicColumn.getDicColumnPK().getTablecode();
			List<DicColumn> tablecodeSet = null;
			if (cacheMapByTablecode.containsKey(tablecode))
			{
				tablecodeSet = (List<DicColumn>) cacheMapByTablecode
						.get(tablecode);
			} else
			{
				tablecodeSet = new ArrayList<DicColumn>();
			}
			tablecodeSet.add(dicColumn);
			cacheMapByTablecode.put(tablecode, tablecodeSet);

			// 数据库冗余字段缓存
			if (!cacheMapByTablecodeAndRddcolumn.containsKey(tablecode))
			{
				cacheMapByTablecodeAndRddcolumn.put(tablecode,
						new ArrayList<DicColumn>());
			}
			boolean dbcolumn = dicColumn.getDbcolumn();
			boolean rddcolumn = dicColumn.getRddcolumn();
			if (dbcolumn && rddcolumn)
			{
				if (cacheMapByTablecodeAndRddcolumn.containsKey(tablecode))
				{
					tablecodeSet = (List<DicColumn>) cacheMapByTablecodeAndRddcolumn
							.get(tablecode);
				} else
				{
					tablecodeSet = new ArrayList<DicColumn>();
				}
				tablecodeSet.add(dicColumn);
				cacheMapByTablecodeAndRddcolumn.put(tablecode, tablecodeSet);
			}

			// 数据来源表缓存
			if (!cacheMapBySourcetable.containsKey(tablecode))
			{
				cacheMapBySourcetable
						.put(tablecode, new ArrayList<DicColumn>());
			}
			String sourcetable = dicColumn.getSourcetable();
			List<DicColumn> sourcetableSet = null;
			if (cacheMapBySourcetable.containsKey(sourcetable))
			{
				sourcetableSet = (List<DicColumn>) cacheMapBySourcetable
						.get(sourcetable);
			} else
			{
				sourcetableSet = new ArrayList<DicColumn>();
			}
			sourcetableSet.add(dicColumn);
			cacheMapBySourcetable.put(sourcetable, sourcetableSet);

			// 冗余字段来源表缓存
			if (!cacheMapByRddsourcetable.containsKey(tablecode))
			{
				cacheMapByRddsourcetable.put(tablecode,
						new ArrayList<DicColumn>());
			}
			String rddsourcetable = dicColumn.getRddsourcetable();
			if (dbcolumn && !ViewUtil.isNuLLStr(rddsourcetable))
			{
				List<DicColumn> rddsourcetableSet = null;
				if (cacheMapByRddsourcetable.containsKey(rddsourcetable))
				{
					rddsourcetableSet = (List<DicColumn>) cacheMapByRddsourcetable
							.get(rddsourcetable);
				} else
				{
					rddsourcetableSet = new ArrayList<DicColumn>();
				}
				rddsourcetableSet.add(dicColumn);
				cacheMapByRddsourcetable.put(rddsourcetable, rddsourcetableSet);
			}
		}

		// 排序处理
		Set<String> tablecodes = cacheMapByTablecode.keySet();
		for (String tablecode : tablecodes)
		{
			ArrayList<DicColumn> dicColumns = (ArrayList<DicColumn>) cacheMapByTablecode
					.get(tablecode);
			sort(dicColumns);
			cacheMapByTablecode.put(tablecode, dicColumns);
		}

		Set<String> sourcetables = cacheMapBySourcetable.keySet();
		for (String sourcetable : sourcetables)
		{
			List<DicColumn> dicColumns = (List<DicColumn>) cacheMapBySourcetable
					.get(sourcetable);
			sort(dicColumns);
			cacheMapBySourcetable.put(sourcetable, dicColumns);
		}

		ViewCacheUtil.put2ConfigDataCacheMap(cacheMapByPk_key, cacheMapByPk);
		ViewCacheUtil.put2ConfigDataCacheMap(cacheMapByTablecode_key,
				cacheMapByTablecode);
		ViewCacheUtil.put2ConfigDataCacheMap(cacheMapBySourcetable_key,
				cacheMapBySourcetable);
		ViewCacheUtil.put2ConfigDataCacheMap(cacheMapByRddsourcetable_key,
				cacheMapByRddsourcetable);
		return result;
	}
}
